<script setup lang="ts">
import { Cell } from '@antv/x6'
import { PromiseType } from '@/typings'
import { initAMap } from '@utils/amap'
import { createVNode, render } from 'vue'
import { GatewayDTO } from '@/api/entity/gateway'
import { createFitViewOverlays } from '@utils/amap/utils'
import { homeDataGatewayAPI } from '@/api/home'
import { FnOperationControl } from '@utils/object-util/periodic-execution/FnOperationControl'

const getNode = inject<{(): Cell }>('getNode')
const currentNode = getNode()
const mapRef = shallowRef<HTMLDivElement>()
let aMap: PromiseType<ReturnType<typeof initAMap>> = null

const dataConfig = currentNode.data.dataConfig
onMounted(() => {
  loadMap()
})
onBeforeUnmount(() => {
  // operationControl && operationControl.stop()
})

// 加载地图
function loadMap () {
  initAMap({
    el: mapRef.value,
    plugins: ['AMap.MarkerCluster'],
    mapOption: {
      center: [116.40, 39.90],
      mapStyle: 'amap://styles/' + currentNode.data.mapOptions.style
    }
  }).then(async (res) => {
    aMap = res
  })
}

const runTypeDic = {
  gatewayDistribution: {
    run: gatewayDistribution,
    name: '网关分布'
  }
}
const dataType = ref('')
function run (data: any) {
  dataType.value = currentNode.data.dataConfig.dataOption.dataType
  if (dataType) {
    runTypeDic[dataType.value]?.run()
  }
}

// region TODO 地图主题
function updateMapStyle () {
  aMap.map.setMapStyle('amap://styles/' + currentNode.data.mapOptions.style)
}
// endregion

// region TODO 网关分布
async function gatewayDistribution () {
  await loadCluster()
  initInfoWindow()
}

// region TODO 聚合标记
let cluster: AMap.MarkerCluster = null
// 加载聚合标记
async function loadCluster () {
  await import('~icons/traffic/location-pedestal2').then((e) => {
    const div = document.createElement('div')
    render(createVNode(e.default), div)
    iconSvgStr = div.innerHTML
  })
  cluster = new AMap.MarkerCluster(aMap.map, [], {
    gridSize: 50,
    maxZoom: 13,
    renderMarker (e) {
      const status = e.data[0].status
      const marker = e.marker
      const icon = getMaskerIcon()
      icon.style.color = { 1: '#1570BB', 2: '#86909C', 3: '#FC5555' }[status] || 'black'
      marker.setContent(icon)
      marker.on('click', () => {
        openInfoWindow(e.data[0])
      })
    }
  })
  startRealTimeGatewayList()
}
// 设置聚合数据
function setClusterData (isFitView = false, _data: GatewayDTO[]) {
  const data = _data.reduce((ret, item) => {
    if (item.latitudeLongitude) {
      const status = item.alarmStatus ? 3 : item.status ? 1 : 2
      ret.push({ lnglat: item.latitudeLongitude.split(','), data: item, status })
    }
    return ret
  }, [])
  isFitView && data.length && aMap.map.setFitView(createFitViewOverlays(aMap.AMap, data))
  cluster.setData(data)
}
// 点标记图标
let iconSvgStr: string = null
function getMaskerIcon () {
  const div = document.createElement('div')
  div.style.width = '20px'
  div.style.height = '28px'
  div.innerHTML = iconSvgStr
  div.firstElementChild.setAttribute('width', '100%')
  div.firstElementChild.setAttribute('height', '100%')
  return div
}
// endregion

// region TODO 网关数据
const gatewayStatusStatistics = shallowRef({
  // 报警数量
  alarmCount: 0,
  // 离线数量
  offlineCount: 0,
  // 在线数量
  onlineCount: 0
})
// 获取网关列表
async function getGatewayList (e: { isFirstRun: boolean }) {
  homeDataGatewayAPI().then((res) => {
    res.result().then((rdata) => {
      const data = rdata.data || {}
      gatewayStatusStatistics.value = data as any
      setClusterData(e.isFirstRun, data.gatewayList || [])
    })
  })
}

// 定时请求
let operationControl: FnOperationControl = null
// 开始获取网关实时数据
function startRealTimeGatewayList () {
  operationControl = new FnOperationControl({
    fn: getGatewayList, timeout: 60000
  })
}
onBeforeUnmount(() => {
  operationControl && operationControl.stop()
})
// endregion

// region TODO 信息窗口
const mapInfoWindowRef = shallowRef<HTMLDivElement>()
const infoWindowData = ref<GatewayDTO>({})
let infoWindow: AMap.InfoWindow = null
function initInfoWindow () {
  infoWindow = new AMap.InfoWindow({
    isCustom: true,
    anchor: 'top-left',
    closeWhenClickMap: true,
    offset: new AMap.Pixel(0, 0)
  })
  infoWindow.setContent(mapInfoWindowRef.value)
}
function openInfoWindow (masterData) {
  infoWindowData.value = masterData.data
  infoWindow.open(aMap.map, masterData.lnglat)
}
// function closeInfoWindow () {
//   infoWindowData.value = {}
//   infoWindow.close()
// }
// endregion
onBeforeUnmount(() => {
  aMap.map.destroy()
})
// endregion

currentNode.data.expose = {
  run,
  updateMapStyle
}
</script>

<template>
  <div class="position-relative wh-100">
    <div ref="mapRef" style="width: 100%;height: 100%" />
    <!--图例-->
    <div v-if="dataType === 'gatewayDistribution'" class="map-legend position-absolute">
      <div class="map-legend__item">
        <span class="title">在线</span>
        <span class="value">{{ gatewayStatusStatistics.onlineCount || 0 }}</span>
      </div>
      <div class="map-legend__item">
        <span class="title">离线</span>
        <span class="value">{{ gatewayStatusStatistics.offlineCount || 0 }}</span>
      </div>
      <div class="map-legend__item">
        <span class="title">报警</span>
        <span class="value">{{ gatewayStatusStatistics.alarmCount || 0 }}</span>
      </div>
    </div>
    <!-- 信息窗口 -->
    <div hidden>
      <div ref="mapInfoWindowRef" class="c_card-white map__info-window" style="width: 285px;min-height: 165px;">
        <div class="c_card_header bor-divider-b fw-4">
          <!--<img src="./images/map__info-window.png" alt="" class="c_header_icon" style="width: 10px;height: 10px;">-->
          <div class="c_card-title">{{ infoWindowData.name }}</div>
        </div>
        <!--网关状态-->
        <div class="info-item">
          <span class="label">网关状态：</span>
          <span class="value">{{ infoWindowData.status ? '在线' : '离线' }}</span>
        </div>
        <!--网关位置-->
        <div class="info-item">
          <span class="label">网关位置：</span>
          <span class="value">{{ infoWindowData.address }}</span>
        </div>
        <!--报警状态-->
        <div class="info-item">
          <span class="label">报警状态：</span>
          <span class="value">{{ infoWindowData.alarmStatus ? '报警' : '无' }}</span>
        </div>
      </div>
    </div>
  </div>
</template>

<style scoped lang="scss">
//网关分布 - 图例
.map-legend {
  width: 131px;height: 126px;
  top: 12px;left: 12px;
  background: #F6F8F9;
  border-radius: 4px;
  padding: 16px 24px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  .map-legend__item {
    height: 21px;
    color: var(--el-text-color-primary);
    .title {
      font-size: 14px;
      display: inline-flex;
      align-items: center;
      &:before {
        content: " ";
        display: inline-block;
        width: 12px;
        height: 12px;
        border-radius: 6px;
        margin-right: 16px;
      }
      &:after {
        content: " ";
        display: inline-block;
        width: 2px;
        height: 13px;
        background-color: #E1E5F4;
        margin-left: 8px;
      }
    }
    .value {
      display: inline-block;
      width: 16px;
      text-align: right;
    }
    &:nth-child(1) .title:before {
      background-color: var(--yk-color-primary);
    }
    &:nth-child(2) .title:before {
      background-color: var(--yk-color-secondary);
    }
    &:nth-child(3) .title:before {
      background-color: var(--yk-color-danger);
    }
  }
}
// 网关布局 - 地图信息窗体
.map__info-window {
  .info-item {
    margin-top: 12px;
    .label {
      font-size: 14px;
      color: #9E9E9E;
    }
    .value {
      font-size: 14px;
      color: #131414;
    }
  }

}
</style>
